import Axios from "axios";
import type { AxiosRequestConfig, Method } from "axios";
import { showFailToast } from "vant";
import type { BasicResType } from "#/basic";
import { start, close } from "./nprogress";
/**
 * 请求失败后的错误统一处理
 * @param {Number} status 请求失败的状态码
 */
const errorHandle = (status: number | string) => {
  // 状态码判断
  switch (status) {
    case 302:
      showFailToast("接口重定向了(302)！");
      break;
    case 400:
      showFailToast("请求错误(400)");
      break;
    case 401: //重定向
      showFailToast("请重新登录(401)");
      break;
    case 403:
      showFailToast("拒绝访问(403)");
      break;
    case 404:
      showFailToast("请求出错(404)");
      break;
    case 406:
      showFailToast("请求的格式不正确(406)");
      break;
    case 408:
      showFailToast(" 请求超时(408)");
      break;
    case 410:
      showFailToast("请求的资源不存在(410)");
      break;
    case 500:
      showFailToast("服务器错误(500)");
      break;
    case 501:
      showFailToast("服务未实现(501)");
      break;
    case 502:
      showFailToast("网关错误(502)");
      break;
    case 503:
      showFailToast("服务不可用(503)");
      break;
    case 504:
      showFailToast("网络超时(504)");
      break;
    case 505:
      showFailToast("HTTP版本不受支持(505)");
      break;
    default:
      showFailToast("服务异常，请稍后再试(status)");
  }
};

// 定义接口
interface PendingType {
  url?: string;
  method?: Method | string;
  params: any;
  data: any;
  cancel: any;
}
// 取消重复请求
const pending: Array<PendingType> = [];
const CancelToken = Axios.CancelToken;

// 移除重复请求
const removePending = (config: AxiosRequestConfig) => {
  for (const key in pending) {
    const item: number = +key;
    const list: PendingType = pending[key];
    if (
      list.url === config.url &&
      list.method === config.method &&
      JSON.stringify(list.params) === JSON.stringify(config.params) &&
      JSON.stringify(list.data) === JSON.stringify(config.data)
    ) {
      // 执行取消操作
      list.cancel("操作太频繁，请稍后再试!");
      pending.splice(item, 1);
    }
  }
};

/* 实例化请求配置 */
export const instance = Axios.create({
  headers: {},
  // 请求时长
  timeout: 1000 * 30,
  // baseURL: 'https://localhost:8080',
});

/**
 * 请求拦截器
 */
instance.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    removePending(config);
    start();
    config.cancelToken = new CancelToken((c) => {
      pending.push({
        url: config.url,
        method: config.method,
        params: config.params,
        data: config.data,
        cancel: c,
      });
    });
    return config;
  },
  (error) => {
    showFailToast(error.data.error.message);
    return Promise.reject(error.data.error.message);
  }
);

// 响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 请求成功
    close();
    if (response.status === 200) {
      return Promise.resolve(response);
    } else {
      errorHandle(response.status);
      return Promise.reject(response);
    }
    // 请求失败
  },
  function (error) {
    const { response } = error;
    errorHandle(response.status);
    if (response) {
      return Promise.reject(response);
    } else {
      return Promise.reject(error);
    }
  }
);

export default function request(
  config: AxiosRequestConfig
): Promise<BasicResType> {
  config.method = config.method || "GET";
  return instance(config)
    .then((res) => {
      const resData = res.data;
      return resData;
    })
    .catch((error) => {
      return {
        code: error.code,
        message: error.msg || "",
        result: null,
      };
    });
}
